#include <stdio.h>              // 标准输入输出
#include <stdlib.h>             // 标准函数库
#include <string.h>             // 字符串处理(操作字符数组)

#include "ohos_init.h"          // 用于初始化服务(services)和功能(features)
#include "cmsis_os2.h"          // CMSIS-RTOS API V2

#include "temp-humi_sensor.h"   // 环境监测板AHT20数字温湿度传感器接口
#include "wifi_connecter.h"     // easy wifi (station模式)
#include "mqtt_task.h"          // MQTT接口

// 定义一系列宏，用于标识SSID、密码、加密方式等，请根据实际情况修改
#define PARAM_HOTSPOT_SSID "jit-OpenAtom"           // AP名称
#define PARAM_HOTSPOT_PSK "jitopenatom"      // AP密码
#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // 安全类型，定义在wifi_device_config.h中

// 根据之前的“MQTT连接华为云”课程，定义连接需要的参数：

// 平台接入地址
#define PARAM_SERVER_ADDR "192.168.31.213"

// 端口号，MQTT协议对应的是1883
#define PARAM_SERVER_PORT "1883"

// 客户端ID
#define PARAM_CLIENT_ID "Pegasus0001"

// 用户名
#define PARAM_USER_NAME "Pegasus0001"

// 密码
#define PARAM_PASSWORD "Pegasus0001"

// 主线程函数
static void mqttDemoTask(void *arg)
{
    (void)arg;

    // 连接AP
    WifiDeviceConfig config = {0};                      // 定义热点配置
    strcpy(config.ssid, PARAM_HOTSPOT_SSID);            // 设置热点配置中的SSID
    strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);     // 设置热点配置中的密码
    config.securityType = PARAM_HOTSPOT_TYPE;           // 设置热点配置中的加密方式
    osDelay(10);
    int netId = ConnectToHotspot(&config);              // 连接到热点
    if (netId < 0)                                      // 检查是否成功连接到热点
    {
        printf("Connect to AP failed!\r\n");
        return;
    }

    // 初始化并启动MQTT任务，连接MQTT服务器
    MqttTaskInit();                                                     // 初始化并启动MQTT任务
    const char *host = PARAM_SERVER_ADDR;                               // MQTT服务器IP地址
    unsigned short port = atoi(PARAM_SERVER_PORT);                      // MQTT服务器端口
    const char *clientId = PARAM_CLIENT_ID;                             // MQTT客户端ID
    const char *username = PARAM_USER_NAME;                             // MQTT服务器用户名
    const char *password = PARAM_PASSWORD;                              // MQTT服务器密码
    if (MqttTaskConnect(host, port, clientId, username, password) != 0) // 连接MQTT服务器（华为云）
    {
        printf("Connect to MQTT server failed!\r\n");
        return;
    }

    // 订阅主题
    char *stopic = "$oc/devices/61b2d0834d9b020287fd5da7_Pegasus001/sys/commands/#";    // 主题
    int rc = MqttTaskSubscribe(stopic);                                                 // 订阅主题
    if (rc != 0)                                                                        // 检查是否成功订阅主题
    {
        printf("MQTT Subscribe failed!\r\n");
        return;
    }
    printf("MQTT Subscribe OK\r\n");

    // 上报数字温湿度传感器数据
    //
    // IoTDM平台：https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-dev/all-product
    // 点击一个具体的产品名称 -> 模型定义
    // 什么是产品模型：https://support.huaweicloud.com/devg-iothub/iot_01_0017.html
    // 点击一个具体的产品名称 -> Topic管理
    //
    // 主题：设备消息上报，设备消息用于传输平台无法解析的设备数据
    // 如果仅使用设备接入能力，不使用平台管理设备，可不定义产品模型。
    // $oc/devices/61b2d0834d9b020287fd5da7_Pegasus001/sys/messages/up
    // https://support.huaweicloud.com/api-iothub/iot_06_v5_3016.html
    //
    // 主题：设备上报属性数据
    // $oc/devices/{device_id}/sys/properties/report
    // https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html

    // 主题：设备消息上报
    // char *ptopic = "$oc/devices/61b2d0834d9b020287fd5da7_Pegasus001/sys/messages/up";

    // 主题：设备上报属性数据
    char *ptopic = "$oc/devices/61b2d0834d9b020287fd5da7_Pegasus001/sys/properties/report";

    // 工作循环
    while (1)
    {
        char payload[512] = {0};                            // 消息内容
        float temperature = 0.0f;                           // 温度
        float humidity = 0.0f;                              // 湿度
        if (GetTempHumiLevel(&temperature, &humidity) == 0) //成功获取数字温湿度传感器数据
        {
            // 消息内容采用JSON格式
            //
            // 主题：设备消息上报
            // 格式：https://support.huaweicloud.com/api-iothub/iot_06_v5_3016.html
            // 例如：{"content":{"temperature":22.30,"humidity":50.10}}
            //
            // 主题：设备上报属性数据
            // 格式：https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html
            // 例如：
            // {
            //     "services": [{
            //             "service_id": "smokeDetector",
            //             "properties": {
            //                 "temperature": 22.30
            //             }
            //         },
            //         {
            //             "service_id": "smokeDetector",
            //             "properties": {
            //                 "humidity": 50.10
            //             }
            //         }
            //     ]
            // }
            //
            // 可以简化一下：
            // {
            //     "services": [{
            //         "service_id": "smokeDetector",
            //         "properties": {"temperature": 22.30, "humidity": 50.10}
            //     }]
            // }

            // 主题：设备消息上报
            // snprintf(payload, sizeof(payload),
            //          "{\"content\":{\"temperature\":%.2f,\"humidity\":%.2f}}", temperature, humidity);

            // 主题：设备上报属性数据
            // https://www.bejson.com/ -> 格式化校验 -> 压缩 -> 转义
            //
            // {\"services\":[{\"service_id\":\"smokeDetector\",\"properties\":{\"temperature\":22.30}},{\"service_id\":\"smokeDetector\",\"properties\":{\"humidity\":50.10}}]}
            // snprintf(payload, sizeof(payload),
            //  "{\"services\":[{\"service_id\":\"smokeDetector\",\"properties\":{\"temperature\":%.2f}},{\"service_id\":\"smokeDetector\",\"properties\":{\"humidity\":%.2f}}]}", temperature, humidity);
            //
            // {\"services\":[{\"service_id\":\"smokeDetector\",\"properties\":{\"temperature\":22.30,\"humidity\":50.10}}]}
            snprintf(payload, sizeof(payload),
                     "{\"services\":[{\"service_id\":\"smokeDetector\",\"properties\":{\"temperature\":%.2f,\"humidity\":%.2f}}]}", 
                     temperature, humidity);    // 消息内容采用JSON格式

            int rc = MqttTaskPublish(ptopic, payload);  // 发布消息
            if (rc != 0)                                // 检查是否成功发布消息
                printf("MQTT Publish failed!\r\n");
            else
                printf("MQTT Publish OK\r\n");
        }
        osDelay(500);                                   // 发布消息间隔5秒
    }
}

// 入口函数
static void mqttDemoEntry(void)
{
    // 初始化AHT20数字温湿度传感器
    InitTempHumiSensor();

    // 定义线程属性
    osThreadAttr_t attr;
    attr.name = "mqttDemoTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    // 创建线程
    if (osThreadNew(mqttDemoTask, NULL, &attr) == NULL)
    {
        printf("[mqttDemoEntry] Falied to create mqttDemoTask!\n");
    }
}

// 运行入口函数
SYS_RUN(mqttDemoEntry);
